<template>
    <div>
        <div ref="containRef"></div>
        <canvas ref="canvasRef" :width="width" :height="height"></canvas>
        <br />
        <button @click="renderOnGL"> WebGL 绘制图片</button>
        <br />
        <canvas ref="glRef" :width="width" :height="height"></canvas>
    </div>
</template>
    
<script setup lang='ts'>
import { ref, onMounted } from 'vue'
import * as GLMat from 'gl-matrix'


const width = ref<number>(634);
const height = ref<number>(444);
const canvasRef = ref<HTMLCanvasElement>()
const glRef = ref<HTMLCanvasElement>()
const containRef = ref<HTMLDivElement>()

const renderOnGL = () => {
    const context = canvasRef.value?.getContext('2d');
    const imageData = context?.getImageData(0, 0, width.value, height.value).data;
    if (!imageData) return;


    // const _context = glRef.value?.getContext('2d');
    // if (!_context) return
    // for (let _h = 0; _h < height.value; _h++) {
    //     for (let _w = 0; _w < width.value; _w++) {
    //         const index = (_h * width.value + _w) * 4;
    //         const r = imageData[index]
    //         const g = imageData[index + 1];
    //         const b = imageData[index + 2];
    //         const a = imageData[index + 3];
    //         _context.beginPath();
    //         _context.lineWidth = 1;
    //         _context.strokeStyle = `rgba(${r},${g},${b},${a})`;
    //         _context.moveTo(_w, _h)
    //         _context.lineTo(_w+1, _h+1)
    //         _context.stroke()
    //     }
    // }


    const mat4 = GLMat.mat4.create();
    GLMat.mat4.ortho(mat4, 0, width.value, height.value, 0, -1, 1);

    const gl = glRef.value?.getContext('webgl')
    if (!gl) return;
    gl?.viewport(0, 0, width.value, height.value);

    const veSource = `
        attribute vec4 a_point;

        uniform mat4 proj;

        attribute vec4 a_color;

        varying vec4 ABColor;

        void main(void){
            gl_Position = proj * a_point;
            gl_PointSize  = 1.0;
            ABColor = a_color;
        }
    `

    const faSource = `
    precision mediump float;
    varying vec4 ABColor; // 可接受顶点着色器相同名称参数
    void main(void){
        gl_FragColor  = ABColor;
    }
    `

    const veShader = gl?.createShader(gl.VERTEX_SHADER);
    if (!veShader) return;
    gl?.shaderSource(veShader, veSource);

    const faShader = gl?.createShader(gl.FRAGMENT_SHADER);
    if (!faShader) return;
    gl?.shaderSource(faShader, faSource);

    gl?.compileShader(veShader);
    gl?.compileShader(faShader)


    if (!gl.getShaderParameter(veShader, gl.COMPILE_STATUS)) {
        var err = gl.getShaderInfoLog(veShader);
        alert(err);
        return;
    }
    if (!gl.getShaderParameter(faShader, gl.COMPILE_STATUS)) {
        var err = gl.getShaderInfoLog(faShader);
        alert(err);
        return;
    }

    const program = gl.createProgram();
    if (!program) return
    gl.attachShader(program, veShader);
    gl.attachShader(program, faShader);
    gl.linkProgram(program);
    gl.useProgram(program)


    gl.clearColor(0, 0, 0, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);

    const bufferData = new Float32Array(width.value * height.value * 6);

    for (let _h = 0; _h < height.value; _h++) {
        for (let _w = 0; _w < width.value; _w++) {
            const index = (_h * width.value + _w) * 4;
            const r = imageData[index]
            const g = imageData[index + 1];
            const b = imageData[index + 2];
            const a = imageData[index + 3];
            const _index = (_h * width.value + _w) * 6
            bufferData[_index] = _w;
            bufferData[_index + 1] = _h;
            bufferData[_index + 2] = r / 255;
            bufferData[_index + 3] = g / 255;
            bufferData[_index + 4] = b / 255;
            bufferData[_index + 5] = a / 255;
        }
    }


    const buffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(gl.ARRAY_BUFFER, bufferData, gl.STATIC_DRAW);

    const vierwP = gl.getUniformLocation(program, 'proj');
    gl.uniformMatrix4fv(vierwP, false, mat4)

    const a_point = gl.getAttribLocation(program, 'a_point');
    const a_color = gl.getAttribLocation(program, 'a_color')

    gl.enableVertexAttribArray(a_point);
    gl.vertexAttribPointer(a_point, 2, gl.FLOAT, false, bufferData.BYTES_PER_ELEMENT * 6, 0)

    gl.enableVertexAttribArray(a_color);
    gl.vertexAttribPointer(a_color, 4, gl.FLOAT, false, bufferData.BYTES_PER_ELEMENT * 6, bufferData.BYTES_PER_ELEMENT * 2)

    gl.drawArrays(gl.POINTS, 0, bufferData.length / 6)
}


onMounted(() => {
    const img = new Image();
    import('../assets/images/mao.png').then(res => {
        img.src = res.default;
        img.onload = () => {
            const context = canvasRef.value?.getContext('2d');
            if (!context) return;
            context.drawImage(img, 0, 0)
        }
    })

})

</script>
    
<style scoped lang="less"></style>